﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using V2TEK.NET.SH.Silverlight.Charts.Core.Schedule;
using System.Diagnostics;
using V2TEK.NET.SH.Silverlight.Charts.Core;

namespace V2TEK.NET.SH.Silverlight.Charts.TimeLineHelper
{
    /// <summary>
    /// 根据TimeLineLayout的数据结构将TimeLine绘制出来
    /// 可以设置ItemRendererProvider更改单个日期时间的样式
    /// </summary>
    public class TimeLineViewer : Panel
    {
        private TimeLineLayout _layout;
        public Type ItemRendererProvider = typeof(SimpleTimeLineEntryRenderer);

        List<UIElement> FreeRenderers { get; set; }

        public TimeLineViewer()
        {
            this.FreeRenderers = new List<UIElement>();
        }

        public TimeLineLayout Layout
        {
            get
            {
                return _layout;
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            //Render(_layout);
        }

        ///// <summary>
        ///// 根据Layout绘制Control UI
        ///// </summary>
        ///// <param name="layout"></param>
        //protected void Render(TimeLineLayout layout)
        //{
            
        //}

        protected override Size ArrangeOverride(Size finalSize)
        {
            if (_layout == null || _layout.Items.Count == 0)
            { return base.ArrangeOverride(finalSize); }

            double totalWidth = 0D;
            double zoom = _layout.Zoom;
            double xPosition = _layout.XPosition;
            if (double.IsInfinity(xPosition) || double.IsNaN(xPosition))
                return finalSize;
            int itemsCount =  _layout.Items.Count;
            //加这个判断的原因是在刻度较小时防止多次double 运算
            if (_layout.CurrentDateTimeType.IsUnChangeRange())
            {
                double width = _layout.Items[0].Width / zoom;
                for (int i = 0; i < itemsCount; i++)
                {
                    TimeLineLayoutItem item = _layout.Items[i];
                    UIElement renderer = base.Children[i];
                    renderer.Arrange(new Rect((item.X - xPosition)/zoom, item.Y, width, item.Height));
                    totalWidth += item.Width;
                }
            }
            else
            {
                for (int i = 0; i < itemsCount; i++)
                {
                    TimeLineLayoutItem item = _layout.Items[i];
                    UIElement renderer = base.Children[i];
                    renderer.Arrange(new Rect((item.X - xPosition) / zoom, item.Y, item.Width / zoom, item.Height));
                    totalWidth += item.Width;
                }
            }

            return finalSize;//new Size(totalWidth, _layout.Items[0].Height);
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            if (_layout== null || _layout.Items.Count == 0)
            { return base.MeasureOverride(availableSize); }

            double totalWidth = 0D;
            double zoom = _layout.Zoom;

            if (_layout.CurrentDateTimeType.IsUnChangeRange())
            {
                double width = _layout.Items[0].Width / zoom;
                for (int i = 0; i < _layout.Items.Count; i++)
                {
                    TimeLineLayoutItem item = _layout.Items[i];
                    UIElement renderer = base.Children[i];

                    renderer.Measure(new Size(width, item.Height));
                    totalWidth += width;
                }
            }
            else
            {
                for (int i = 0; i < _layout.Items.Count; i++)
                {
                    TimeLineLayoutItem item = _layout.Items[i];
                    UIElement renderer = base.Children[i];

                    double width = item.Width/zoom;
                    renderer.Measure(new Size(width, item.Height));
                    totalWidth += width;
                }
            }
            
            return new Size(totalWidth, _layout.Items[0].Height);
        }

        private void EnsureItemRenderers(int count)
        {
            base.Children.Clear();
            int i = 0;
            while (i < count)
            {
                UIElement renderer = this.NewItemRenderer;
                TimeLineLayoutItem item = _layout.Items[i];
                (renderer as ITimeLineEntryRenderer).Data = item.Data;
                this.Children.Add(renderer);

                i++;
            }
        }

        public void OnUpdate(object sender, LayoutUpdateEventArgs args)
        {
            _layout = args.Layout as TimeLineLayout;
            EnsureItemRenderers(_layout.Items.Count);
            this.InvalidateArrange();
            this.InvalidateMeasure();
        }

        private UIElement NewItemRenderer
        {
            get
            {
                return Activator.CreateInstance(ItemRendererProvider) as UIElement;
            }
        }
    }
}
